﻿#include "collision.h"


// 矩形碰撞箱
RectangleCollisionBox::RectangleCollisionBox()
    : CollisionBox(CollisionBoxType::Rectangle), x_(0), y_(0), width_(1), length_(1) {}
RectangleCollisionBox::RectangleCollisionBox(float x, float y, float width, float length)
    : CollisionBox(CollisionBoxType::Rectangle), 
    x_(std::abs(x)), y_(std::abs(y)), width_(std::abs(width)), length_(std::abs(length)) {}

float RectangleCollisionBox::getX() const { return x_; }
float RectangleCollisionBox::getY() const { return y_; }
float RectangleCollisionBox::getWidth() const { return width_; }
float RectangleCollisionBox::getLength() const { return length_; }

bool RectangleCollisionBox::setX(float x) {
    if (x >= 0) {
        x_ = x;
        return true;
    }
    return false;
}
bool RectangleCollisionBox::setY(float y) {
    if (y >= 0) {
        y_ = y;
        return true;
    }
    return false;
}
bool RectangleCollisionBox::setWidth(float width) {
    if (width >= 0) {
        width_ = width;
        return true;
    }
    return false;
}
bool RectangleCollisionBox::setLength(float length) {
    if (length >= 0) {
        length_ = length;
        return true;
    }
    return false;
}


// 多态碰撞
bool RectangleCollisionBox::checkCollision(const CollisionBox& other) const {
    return other.checkCollisionWithRectangle(*this);
}

// 矩形与点的碰撞检测 (与点-矩形检测对称)
bool RectangleCollisionBox::checkCollisionWithPoint(const PointCollisionBox& point) const {
    return point.checkCollisionWithRectangle(*this);
}

// 矩形与矩形的碰撞检测（AABB算法）
bool RectangleCollisionBox::checkCollisionWithRectangle(const RectangleCollisionBox& rect) const {
    return (x_ <= rect.getX() + rect.getWidth() &&
        x_ + width_ >= rect.getX() &&
        y_ <= rect.getY() + rect.getLength() &&
        y_ + length_ >= rect.getY());
}

// 矩形与圆形的碰撞检测
bool RectangleCollisionBox::checkCollisionWithCircle(const CircleCollisionBox& circle) const {
    // 找到矩形上离圆心最近的点
    float closestX = std::max(x_, std::min(circle.getX(), x_ + width_));
    float closestY = std::max(y_, std::min(circle.getY(), y_ + length_));

    // 计算最近点与圆心的距离
    float dx = closestX - circle.getX();
    float dy = closestY - circle.getY();
    return (dx * dx + dy * dy) <= (circle.getRadius() * circle.getRadius());
}